from sqlalchemy.orm import create_session;
from sqlalchemy import alias
from pos import Company,Project,Employee,Delivery,Dish,OrderItem
from constants import *
from tables import db
import threading

class BaseDao:

    def getSession(self):
        thread = threading.current_thread();
        if not hasattr(thread,'session'):
            thread.session = create_session(bind=db,autocommit=False);
        return thread.session

class CompanyDao(BaseDao):

    def getCompany(self):
        session = self.getSession()
        q = session.query(Company)
        companys = q.filter_by(id=Company_id).all()
        if not companys:
            company = Company()
            company.id = Company_id
            company.name = 'Happy Elements'
            company.intro = 'Social Game Developer'
            session.add(company)
            session.commit()
            return company
        return companys[0]

    def saveCompanyInfo(self,name,intro):
        session = self.getSession()
        company = self._getCompany(session)
        if not company:
            company = Company()
            company.id = Company_id
            company.name = name
            company.intro = intro
            session.add(company);
        company.name = name
        company.intro = intro
        session.commit()
        return company

class ProjectDao(BaseDao):

    def getAllProject(self,companyId):
        session = self.getSession()
        q = session.query(Project)
        projects = q.filter_by(company_id=companyId).all()
        return projects

    def getProject(self,projectId):
        session = self.getSession()
        q = session.query(Project)
        projects = q.filter_by(id=projectId).all()
        if not projects:
            return None
        return projects[0]

    def removeProject(self,projectId):
        session = self.getSession()
        q = session.query(Project)
        companys = q.filter_by(id=projectId).all()
        if not companys:
            return None
        company = companys[0]
        session.delete(company)
        session.commit()
        return company

    def addProject(self,name,intro,company):
        session = self.getSession();
        project = Project()
        project.name = name
        project.intro = intro
        project.company = company
        session.add(project)
        session.commit()
        return project

class EmployeeDao(BaseDao):

    def getAllEmployee(self):
        session = self.getSession()
        q = session.query(Employee)
        employees  = q.all()
        return employees

    def getProjectEmployee(self,projectId):
        session = self.getSession()
        q = session.query(Employee)
        employees = q.filter_by(project_id=projectId).all()
        return employees

    def getEmployee(self,employeeId):
        session = self.getSession()
        q = session.query(Employee)
        employees = q.filter_by(id=employeeId).all()
        if not employees:
            return None
        return employees[0]

    def removeEmployee(self,employeeId):
        session = self.getSession()
        q = session.query(Employee)
        employees = q.filter_by(id=employeeId).all;
        if not employees:
            return None
        employee = employees[0]
        session.delete(employee)
        session.commit()
        return employee

    def addEmployee(self,name,gender,project):
        session = self.getSession()
        employee = Employee()
        employee.name = name
        employee.gender = gender
        employee.project = project
        session.add(employee)
        session.commit()
        return employee

    def changeProject(self,employeeId,project):
        session = self.getSession()
        employee = self.getEmployee(employeeId)
        if not employee:
            return None
        employee.project = project
        session.commit()
        return employee

class DeliveryDao(BaseDao):
    
    def getAllDeliveries(self):
        session = self.getSession()
        q = session.query(Delivery)
        deliveries = q.all()
        return deliveries
    
    def addDelivery(self,name,intro,address,phone):
        session = self.getSession()
        delivery = Delivery()
        delivery.name = name
        delivery.intro = intro
        delivery.address = address
        delivery.phone = phone
        session.add(delivery)
        session.commit()
        return delivery
    
    def getDelivery(self,deliveryId):
        session = self.getSession()
        q = session.query(Delivery)
        q.filter_by(id = deliveryId)
        deliveries = q.all()
        if not deliveries : 
            return None
        return deliveries[0]
    
    def removeDelivery(self,deliveryId):
        session = self.getSession()
        delivery = self.getDelivery(deliveryId)
        if not delivery : 
            return None
        session.delete(delivery)
        session.commit()
        return delivery
    
class DishDao(BaseDao):
    
    def getDeliveryDishes(self,deliveryId):
        session = self.getSession()
        q = session.query(Dish)
        dishes = q.filter_by(delivery_id=deliveryId).all()
        return dishes
    
    def getDish(self,dishId):
        session = self.getSession()
        q = session.query(Dish)
        dishes = q.filter_by(id = dishId).all()
        if not dishes : 
            return None
        return dishes[0]
    
    def removeDish(self,dishId):
        session = self.getSession()
        dish = self.getDish(dishId)
        if not dish:
            return dish
        session.delete(dish)
        session.commit()
        return dish
    
    def addDish(self,name,price,delivery):
        session = self.getSession()
        dish = Dish()
        dish.name = name
        dish.price = price
        dish.delivery = delivery
        session.add(dish)
        session.commit()
        return dish

class OrderItemDao(BaseDao):

    def addOrderItem(self,employeeId,dishId,ip,orderTime):
        session = self.getSession()
        order = OrderItem()
        order.employee_id = employeeId
        order.dish_id = dishId
        order.ip = ip
        order.order_time = orderTime
        session.add(order)
        session.commit()
        return order

    def removeOrderItem(self,orderItemId):
        session = self.getSession()
        order = self.getOrderItem(orderItemId)
        if not order:
            return None
        session.delete(order)
        session.commit()
        return order

    def getOrderItem(self,orderItemId):
        session = self.getSession()
        q = session.query(OrderItem)
        orders = q.filter_by(id = orderItemId).all()
        if not orders : 
            return None
        return orders[0]

    def getAllOrderItems(self):
        session = self.getSession()
        q = session.query(OrderItem)
        orders = q.all()
        return orders

    def getProjectOrderItems(self,projectId):
        session = self.getSession()
        o = alias(OrderItem)
        e = alias(Employee)
        q = session.query(o).join(e,e.id == o.employeeId)
        orders = q.filter(e.project_id == projectId).all()
        return orders

    def getEmployeeOrderItem(self,employeeId):
        session = self.getSession()
        q = session.query(OrderItem)
        orders = q.filter_by(employee_id = employeeId).all()
        if not orders:
            return None
        return orders[0]
    
companyDao = CompanyDao()
projectDao = ProjectDao()
employeeDao = EmployeeDao()
deliveryDao = DeliveryDao()
dishDao = DishDao()
orderDao = OrderItemDao()